#ifndef MERGETOALL_HPP
#define MERGETOALL_HPP

#include <QString>
#include <QList>
#include <QMetaType>

// 定义 MergeToAll 结构体，将 Reference 和 Source 数据合并
struct MergeToAll {
    QString id;
    QString node;
    QDateTime date;            // 从 "01#2024-12-13" 中获取日期
    int subFolderNumber;       // 从子文件夹名 "1" 中获取
    int fileNumber;            // 从文件名 "14.xml" 提取 14

    QString name;
    int type;                  // input=0, output=1, servo=2
    int value;                 // True=1, False=0
    QString board;
    QString slot;
    QDateTime duraction;       // Source.time + fileNumber 秒
    int slotval;               // 从 Source.slotsz 中根据 sslot 索引取得值
    QList<int> slotsz;


    QString sname;
    int stype;   // input=0, output=1, servo=2
    int svalue;  // True=0, False=1
    QString sboard;
    QString sslot;

    QString ename;
    int etype;   // input=0, output=1, servo=2
    int evalue;  // True=0, False=1
    QString eboard;
    QString eslot;


    // 无参构造函数
    MergeToAll() : subFolderNumber(-1), fileNumber(-1) { }

    // 有参构造函数
    MergeToAll(const QString &node_, const QDateTime &date_, int subFolderNumber_, int fileNumber_, const Reference &ref, const Source &src)
        : id(QUuid::createUuid().toString()), node(node_), date(date_), subFolderNumber(subFolderNumber_), fileNumber(fileNumber_) {


        name = isStartOrEnd(ref.svalue,src.slotsz, ref.sslot)? ref.sname : ref.ename;
        type = isStartOrEnd(ref.svalue,src.slotsz, ref.sslot)?  ref.stype:ref.etype;
        board = isStartOrEnd(ref.svalue,src.slotsz, ref.sslot)? ref.sboard:ref.eboard;
        slot =   isStartOrEnd(ref.svalue,src.slotsz, ref.sslot)? ref.sslot: ref.eslot;
        duraction = isStartOrEnd(ref.svalue,src.slotsz, ref.sslot) ?  createTimeFromNumber(date_.date(), fileNumber_, src.time) : createTimeFromNumber(date_.date(), fileNumber_, src.time);
        slotval = isStartOrEnd(ref.svalue,src.slotsz, ref.sslot) ?  ref.svalue : ref.evalue;
        slotsz = src.slotsz;

        sname = ref.sname;
        stype = ref.stype;   // input=0, output=1, servo=2
        svalue = ref.svalue;  // True=0, False=1
        sboard = ref.sboard;
        sslot = ref.sslot;

        ename = ref.ename;
        etype = ref.etype;   // input=0, output=1, servo=2
        evalue = ref.evalue;  // True=0, False=1
        eboard = ref.eboard;
        eslot = ref.eslot;

    }

    // toJson 函数
    QJsonObject toJson() const {
        QJsonObject obj;
        obj["id"] = id;
        obj["node"] = node;
        obj["date"] = date.toString(Qt::ISODate);
        obj["subFolderNumber"] = subFolderNumber;
        obj["fileNumber"] = fileNumber;

        obj["name"] = name;
        obj["type"] = type;
        obj["board"] = board;
        obj["slot"] = slot;

        obj["duraction"] = duraction.toString("HH:mm:ss.zzz");
        obj["slotval"] = slotval;

        obj["sname"] = sname;
        obj["stype"] = stype;
        obj["svalue"] = svalue;
        obj["sboard"] = sboard;
        obj["sslot"] = sslot;

        obj["ename"] = ename;
        obj["etype"] = etype;
        obj["evalue"] = evalue;
        obj["eboard"] = eboard;
        obj["eslot"] = eslot;

        return obj;
    }




    /**
        判断是否Start还是End
    */
    int isStartOrEnd(const int &refval, const QList<int> &slotsz, const QString &slotIndexStr) {
        return refval == getValueFromSlots(slotsz, slotIndexStr);
    }

    // 根据 fileNumber 和 Source.time 构造时间
    // 例如: Source.time = "20:41:18", fileNumber=14 -> 14:20:41.018
    QDateTime createTimeFromNumber(const QDate &date, int fileNumber, const QString &sourceTime) {
        // 检查 fileNumber 是否在有效的小时范围内
        if (fileNumber < 0 || fileNumber > 23) {
            qDebug() << "Invalid fileNumber (hour):" << fileNumber;
            return QDateTime();
        }

        if (sourceTime.isEmpty()) {
            qDebug() << "Source time is empty.";
            return QDateTime();
        }

        // 假设 sourceTime 格式为 "mm:ss:zzz"
        QStringList timeParts = sourceTime.split(':');
        if (timeParts.size() != 3) {
            qDebug() << "Invalid sourceTime format:" << sourceTime;
            return QDateTime();
        }

        bool okMinute, okSecond, okMilli;
        int minute = timeParts[0].toInt(&okMinute);
        int second = timeParts[1].toInt(&okSecond);
        int millisecond = timeParts[2].toInt(&okMilli);

        if (!okMinute || !okSecond || !okMilli) {
            qDebug() << "Failed to parse sourceTime parts:" << timeParts;
            return QDateTime();
        }

        // 检查分钟、秒钟和毫秒是否在有效范围内
        if (minute < 0 || minute > 59) {
            qDebug() << "Invalid minutes:" << minute;
            return QDateTime();
        }
        if (second < 0 || second > 59) {
            qDebug() << "Invalid seconds:" << second;
            return QDateTime();
        }
        if (millisecond < 0 || millisecond > 999) {
            qDebug() << "Invalid milliseconds:" << millisecond;
            return QDateTime();
        }

        // 构造 QTime 对象
        QTime constructedTime(fileNumber, minute, second, millisecond);
        if (!constructedTime.isValid()) {
            qDebug() << "Constructed time is invalid:" << constructedTime.toString();
            return QDateTime();
        }

        // 返回 QDateTime 对象
        return QDateTime(QDate::currentDate(), constructedTime);
    }


    // 从 slotsz 中根据索引返回值
    // 假设 slotsz 是 "0,1,0,1..." 等数字组成的字符串，已转换为 QList<int>
    int getValueFromSlots(const QList<int> &slotsz, const QString &slotIndexStr) {
        bool ok = false;
        int index = slotIndexStr.toInt(&ok);
        if (!ok || index < 0 || index >= slotsz.size()) return -1;

        return slotsz.at(index);
    }
};

// 在结构体定义之后声明元类型
Q_DECLARE_METATYPE(MergeToAll)



#endif // MERGETOALL_HPP
